---
order: 1
title: 2D 纹理
type: 图形
group: 纹理
label: Graphics/Texture
---

2D 纹理（[Texture2D](/apis/core/#Texture2D)）是最常用的美术资源，使用二维 UV 坐标进行采样。

## 创建

在编辑器中可以方便地导入一张 2D 纹理，按照路径 **[资产面板](/docs/assets/interface)** -> **右键上传** -> **选择 Texture2D** -> **选择对应贴图** -> **2D 纹理资产创建完毕** 操作即可。

<Image src="https://mdn.alipayobjects.com/huamei_yo47yq/afts/img/A*71QKTYuRSyAAAAAAAAAAAAAADhuCAQ/original" alt="image.png" style={{zoom: "50%"}} />

同样的，在脚本中可以通过 [ResourceManager](/apis/core/#ResourceManager) 加载图片获取对应的 2D 纹理：

```typescript
const textureResource = {
  type: AssetType.Texture2D,
  url: `图片url`,
};

engine.resourceManager
  .load(textureResource, cubeTextureResource)
  .then((resource) => {
    // 引擎支持的2D纹理
    const texture = resource;
    // 接下来可以将纹理应用到材质上或者进行其他操作
  });
```

## 方法

| 方法           | 解释                   |
| :------------- | :--------------------- |
| setImageSource | 设置纹理的图像数据源头 |
| setPixelBuffer | 修改纹理对象的图像数据 |
| getPixelBuffer | 获取纹理对象的图像数据 |

### setImageSource

前面提到过，图片、canvas 画布、视频等跟图像相关的数据源都可以用来当作纹理。比如视频就可以通过 [setImageSource](/apis/core/#Texture2D-setImageSource) 接口上传到纹理：

```typescript
// 拿到视频标签，即 HTMLVideoElement
const video = document.getElementsByTagName("video")[0];

// 加载到纹理
texture.setImageSource(video);
```

> `setImageSource` 只能同步那一帧的数据，但是视频每一帧都在变化，如果需要纹理同步变化，则要在脚本 onUpdate 钩子里面执行

对于视频这类需要频繁更新纹理内容的使用场景，创建纹理的时候需要关闭 mipmap 并设置纹理使用方式为 Dynamic，以获得更好的性能，示例代码如下：

<Playground href="/embed/benchmark-video" />

### setPixelBuffer

纹理底层其实对应着每个像素的颜色值，即 RGBA 通道，我们可以手动填写这些颜色通道的颜色数值，然后通过 [setPixelBuffer](/apis/core/#Texture2D-setPixelBuffer) 接口传到纹理中：

```typescript
const texture = new Texture2D(engine, 1, 1);
// 将该像素设置为红色，即 R 通道为 255。
const data = new Uint8Array([255, 0, 0, 255]);
texture.setPixelBuffer(data);
```

### getPixelBuffer

同样的，我们可以读取这些颜色通道的颜色数据：

```typescript
const texture = new Texture2D(engine, width, height);
// 对纹理做了一系列处理
// ···
// 用来保存颜色信息的数组，它的大小和要读取的数据量相等
const data = new Uint8Array(width * height * 4);
texture.getPixelBuffer(0, 0, width, height, 0, data);
```

## 使用

将纹理赋予材质球的相应属性，可以开启不同的渲染功能，如添加基础颜色纹理，可以决定模型的基本色调。在编辑器中，只需在对应属性选择相应纹理即可。

<Image src="https://mdn.alipayobjects.com/huamei_yo47yq/afts/img/A*toooTZvkC60AAAAAAAAAAAAADhuCAQ/original" alt="image.png" style={{zoom: "50%"}} />

对应的，在脚本中，可以这样设置：

```typescript
const material = new PBRMaterial(engine);
const texture = 生成纹理(); // 上文所示，不再赘述

material.baseTexture = texture;
```

## 色彩膨胀

<Image src="https://mdn.alipayobjects.com/huamei_yo47yq/afts/img/A*ACbwSKO2LHwAAAAAAAAAAAAADhuCAQ/original" alt="image.png" style={{zoom: "50%"}} />

为了解决带透明像素图片在 Alpha 值突变处出现黑边的问题，编辑器内置了色彩膨胀功能。该功能是通过将图片中所有透明像素的 RGB 值改写为与其最临近非完全透明像素的 RGB 值，达到去除图片黑边的效果。

| 选项             | 解释                                            |
| :--------------- | :---------------------------------------------- |
| 范围 Alpha Range | 阈值，透明像素 Alpha 值小于此阈值, RGB 值被修改 |
| 大小 Alpha Value | 透明像素填充后的 Alpha 值                       |

## 导出配置

<Image src="https://mdn.alipayobjects.com/huamei_yo47yq/afts/img/A*_aepTLE47-gAAAAAAAAAAAAADhuCAQ/original" alt="image.png" style={{zoom: "50%"}} />

[项目发布](/docs/platform/platform)文档中详细说明了纹理导出时的**全局配置**，若此处勾选 Overwrite 选项时，此资产导出时将遵循**自定义配置**将非**全局配置**。
